using Core.Contracts.Interfaces;

namespace Core.Features
{
    using System;
    using Base;
    using Contracts.Enums;
    using Resources;
    using System.Linq;

    
    public sealed class LockingTime<T> : FeatureBase<object>
    {
        public LockingTime(){}

        public LockingTime(T value) 
            : base(value){ }
        /// <summary>
        /// Obtains the feature name
        /// </summary>
        public override string Name
        {
            get { return "Locking time"; }
        }
        /// <summary>
        /// Obtains the feature group
        /// </summary>
        public override FeatureGroupsEnum FeatureGroup{ get { return FeatureGroupsEnum.TargetingEquipment; } }
        /// <summary>
        /// Obtains the feature type
        /// </summary>
        public override FeaturesEnum FeatureType { get { return FeaturesEnum.LockingTime; } }
        /// <summary>
        /// Obtains or defines the feature unit
        /// </summary>
        public override string Unit { get { return Traduction.label_unit_sec; } }

        /// <summary>
        /// Determines if the feature value is rounded
        /// </summary>
        public override bool IsRounded
        {
            get { return false; }
        }
        public override void SetModifiedValue(IAgent agent, IRobot robot)
        {
            if (agent == null || robot == null) return;
            // extensions
            double extensionBonus = agent.Extensions.SumModifiersValues(FeatureTypesEnum.Robot, this.FeatureType);
            // robot bonus
            double robotBonus = robot.Modifiers.SumModifiersValues(agent.Extensions,FeatureTypesEnum.Robot, this.FeatureType);
            // SensorAmplifiers modules
            double moduleBonus = robot.Modules.SumModifiersValues(FeatureTypesEnum.Robot, this.FeatureType, ModuleGroupsEnum.SensorAmplifiers);
            double numSensorAmp = robot.Modules.Count(g => g.Group == ModuleGroupsEnum.SensorAmplifiers && g.IsActive);


            if (numSensorAmp != 0)
                moduleBonus = moduleBonus / numSensorAmp;
            else moduleBonus = 1;

            // Sensor Connection Bonus

            double sensorconnBonus = agent.Extensions.Where(e => e.GetType() == typeof(Extensions.SensorConnection))
                                                     .SumModifiersValues(FeatureTypesEnum.Module, this.FeatureType);

            // SensorAmplifiers modules + Sensor Connection Bonus

            double SensorTotalBonus = 1;

            if (moduleBonus != 0)

            SensorTotalBonus = (1 - Math.Abs(moduleBonus)) / (1 + Math.Abs(sensorconnBonus));
            SensorTotalBonus = Math.Pow(SensorTotalBonus, numSensorAmp);


            double temp = (double)Value / (1 + (Math.Abs(extensionBonus + (Math.Abs(robotBonus))))) * (SensorTotalBonus);

            // nexus Bonus
            double nexusBonus = robot.Modules.SumModifiersValues(FeatureTypesEnum.Robot, this.FeatureType, ModuleGroupsEnum.NexusModuleLockBooster);
            double nexusSkillBonus = agent.Extensions.Where(e => e.GetType() == typeof(Extensions.NexusAcceleratedTargetLocking))
                                                     .SumModifiersValues(FeatureTypesEnum.Module, this.FeatureType);

            double nexusTotalBonus = 0;

            if (nexusBonus != 0)
            {
                nexusTotalBonus = (1 - Math.Abs(nexusBonus)) / (1 + Math.Abs(nexusSkillBonus));
                nexusTotalBonus = 1 - nexusTotalBonus;
            }
            temp = temp * (1 - nexusTotalBonus);

            
            ModifiedValue = IsRounded
                ? Math.Round(temp, 0, MidpointRounding.AwayFromZero)
                : Math.Round(temp, 2);
        }
        
    }
}